package net.imagine.provider.skyline;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import net.imagine.core.FileKeyGenerator;
import net.imagine.core.ImageInfo;
import net.imagine.core.ResultState;
import net.imagine.core.resize.ImageResizeTask;
import net.imagine.core.resize.ImageResizeTemplate;
import net.imagine.provider.fastdfs.FastDFSFileOperator;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

/**
 * 图片压缩模板的实现
 * 
 * @author wuqh
 * @see ImageResizeTemplate
 */
@Component("imageResizer")
public class ImageResizer extends ImageResizeTemplate {
	private static final Log logger = LogFactory.getLog(ImageResizer.class);
	private FileKeyGenerator fileKeyGen = new SimpleFileKeyGenerator();
	private FastDFSFileOperator fileOperator = null;
	
	@Override
	protected String generateFirstFilename(String fileKey, String originalFilename) {
		String ext = FilenameUtils.getExtension(originalFilename);
		return fileKey + '.' + ext;
	}

	@Override
	protected ResultState storeFile(File fileToStore, String key, String[] fileKeys, int index, ImageResizeTask task) {
		/*
		 * if local just return SUCCESS, if NFS need to copy localFile to NFS
		 * server, we may change to use fastdfs in the future
		 */
		if (fileOperator == null) {
			SkylineImageResizeTask resizeTask = (SkylineImageResizeTask) task;
			long userId = resizeTask.getUserId();
			long albumId = resizeTask.getAlbumId();
			String path = SkylineImagineUtils.generateFilePath("", userId, albumId);
			fileKeys[(index + 1)] = path + key;
			return ResultState.SUCCESS;
		} else {
			try {
				String[] result = fileOperator.uploadFile(fileToStore);
				// String groupName = result[0];
				String remoutKey = result[1];
				fileKeys[(index + 1)] = FilenameUtils.removeExtension(remoutKey);
				return ResultState.SUCCESS;
			} catch (Exception e) {
				logger.warn("上传文件到DFS失败", e);
				return ResultState.STORE_FAILED;
			}
		}

	}

	@Override
	protected ResultState writeImageToFile(File firstFile, InputStream input) {
		try {
			SkylineImagineUtils.writeStreamToFile(firstFile, input);
			return ResultState.SUCCESS;
		} catch (IOException e) {
			logger.warn("IOException occurred when wtrite inputstream to file", e);
			return ResultState.CREATE_ORIGINAL_FILE_FAILED;
		}
	}

	private String generateMiddleAndSmallFilename(String fileKey, int i, String ext) {
		switch (i) {
		case 0:
			return fileKey + "_m." + ext;
		case 1:
			return fileKey + "_s." + ext;
		default:
			return null;
		}
	}

	private String generateResizeOneFilename(String fileKey, int index, ImageResizeTask task, String ext) {
		String defaultFilename = null;
		if (task instanceof MultipartImageResizeTask) {
			MultipartImageResizeTask multipartTask = (MultipartImageResizeTask) task;
			if (multipartTask.isUseDefault()) {
				defaultFilename = multipartTask.getDefaultFilename();
			}
		}
		if (defaultFilename == null) {
			if (index == 0) {
				return fileKey + "." + ext;
			} else {
				return null;
			}
		} else {
			return defaultFilename;
		}

	}

	@Override
	protected void deleteFiles(List<String> filePaths) {
		if(fileOperator != null) {
			for(String file : filePaths) {
				try {
					FileUtils.forceDelete(new File(file));
				} catch (IOException e) {
					logger.warn("delete file failed", e);
				}			
			}
		} else {
			File file = new File(filePaths.get(0));
			try {
				FileUtils.forceDelete(file);
			} catch (IOException e) {
				logger.warn("delete file failed", e);
			}
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected ImageResizeResult processResult(ResultState state, ImageResizeTask task, String[] fileKeys, ImageInfo info) {
		ImageResizeResult result = new ImageResizeResult(state);
		SkylineImageResizeTask resizeTask = (SkylineImageResizeTask) task;
		result.setOriginalFilename(task.getFilename());
		String originalFileKey = info.getOriginalFileKey();
		// 处理最终的结果
		if (state == ResultState.SUCCESS) {
			if (info == null) { // 没有做解析过的压缩必然有问题，特殊处理下
				result.setResultState(ResultState.NOT_IMAGE);
				return result;
			}
			result.setFileSize(resizeTask.getFileSize());
			long userId = resizeTask.getUserId();
			long albumId = resizeTask.getAlbumId();
			String path = SkylineImagineUtils.generateFilePath("", userId, albumId);
			// fileKey带上路径，方便页面生成
			result.setFileKey(path + originalFileKey);
			result.setUserId(userId);
			result.setAlbumId(albumId);

			result.setFileKeys(fileKeys);
			String ext = info.getExt();
			if (!task.isSupportMulitFrame() && SkylineImagineUtils.isExtMultiFrame(ext)) {
				ext = SkylineImagineUtils.DEFAULT_EXT;
			}
			result.setExt(ext);
		}
		return result;
	}

	@Override
	protected String generateResizeFileKey(String originalFileKey, String currentFilename, ImageResizeTask task) {
		return FilenameUtils.getBaseName(currentFilename);
	}

	@Override
	protected String generateFileKey(ImageResizeTask task) {
		SkylineImageResizeTask resizeTask = (SkylineImageResizeTask) task;
		Long userId = resizeTask.getUserId();
		Long albumId = resizeTask.getAlbumId();
		String originalFileKey = resizeTask.getFilename();
		return fileKeyGen.generateFileKey(userId.toString(), albumId.toString(), originalFileKey);
	}

	@Override
	protected String generateFilename(String originalFileKey, int index, ImageResizeTask task, String ext) {
		int length = task.getBaseSizes().length;
		// 系统不支持多帧压缩时，需要把扩展名改为默认的png
		if (!task.isSupportMulitFrame() && SkylineImagineUtils.isExtMultiFrame(ext)) {
			ext = SkylineImagineUtils.DEFAULT_EXT;
		}
		if (length == 1) {
			return generateResizeOneFilename(originalFileKey, index, task, ext);
		}
		if (length == 2) {
			return generateMiddleAndSmallFilename(originalFileKey, index, ext);
		}
		logger.warn("baseSize array is longer than two, check your array size");
		return null;
	}

	@Override
	protected ResultState storeFirstFile(File firstFile, String originalFileileKey, String[] fileKeys,
			ImageResizeTask task) {
		/*
		 * user NFS so just return SUCCESS, we may change to use fastdfs in the
		 * future
		 */
		SkylineImageResizeTask resizeTask = (SkylineImageResizeTask) task;
		long userId = resizeTask.getUserId();
		long albumId = resizeTask.getAlbumId();
		String ext = FilenameUtils.getExtension(firstFile.getName());
		String filename =  originalFileileKey + '.' + ext;
		fileKeys[0] = SkylineImagineUtils.generateFilePath("", userId, albumId, filename);
		return ResultState.SUCCESS;
	};

	protected String generateFilePath(String basePath, String filename, ImageResizeTask task) {
		SkylineImageResizeTask resizeTask = (SkylineImageResizeTask) task;
		Long userId = resizeTask.getUserId();
		Long albumId = resizeTask.getAlbumId();
		return SkylineImagineUtils.generateFilePath(basePath, userId, albumId, filename);
	}

	public void setFileOperator(FastDFSFileOperator fileOperator) {
		this.fileOperator = fileOperator;
	}

}